<template>
    <div class="app-content">
        <Header />
        <div class="content">
            <Sidebar />
            <Main />
        </div>
    </div>
</template>

<script setup lang="ts">
import Header from '@/components/header/header.vue'
import Sidebar from '@/components/sidebar/sidebar.vue'
import Main from '@/components/main/main.vue'
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
import { useGlobalStore } from '@/store/global'
import requestData from '@/config/index'
import { ICardItem } from '@/type/interface'

const requestType = reactive({
    pageNumber:1,
    pageSize:20,
    finsh:false,
    loading:false,
    first:true
})
const cardList = ref<ICardItem[]>([])

const FIRSTWIDTH = 1728
const SECONDWIDTH = 1424
const THIRDWIDTH = 1192
const FOURWIDTH = 960
const FIVEWIDTH = 696

const useGlobal = useGlobalStore()

//监听dom宽度变化
const mainResize = () => {
    const main = document.querySelector('.app-content');
    const content = document.querySelector('.main-content');
    let i = 0
    //const imgList = document.querySelectorAll('.img-item')
    const observer = new ResizeObserver((entries) => {
        entries.forEach(entry => {
            const { inlineSize } = entry.borderBoxSize[0]
            if (entry.target.className == 'app-content') {
                let num = 0
                let width = '0px'
                let contentLeft = '0px'
                let gap = 32
                let display = 'block'
                if (inlineSize >= FIRSTWIDTH) {
                    num = 5,
                    width = '266.66667px'
                    contentLeft = '282.66667px'
                }
                if (inlineSize >= SECONDWIDTH && inlineSize < FIRSTWIDTH) {
                    num = 5,
                    width = 'calc(-21.33333px + 16.66667vw)'
                    contentLeft = 'calc(-9.3333px + 16.66667vw)'
                }
                if (inlineSize >= THIRDWIDTH && inlineSize < SECONDWIDTH) {
                    num = 4,
                    width = 'calc(-16.8px + 20vw)'
                    contentLeft = 'calc(-4.8px + 20vw)'
                    gap = 24
                }
                if (inlineSize >= FOURWIDTH && inlineSize < THIRDWIDTH) {
                    num = 3,
                    width = 'calc(-18px + 25vw)'
                    contentLeft = 'calc(-6px + 25vw)'
                    gap = 24
                }
                if (inlineSize >= FIVEWIDTH && inlineSize < FOURWIDTH) {
                    num = 3
                    gap = 24
                    contentLeft = '0px'
                    display = 'none'
                }
                if (inlineSize < FIVEWIDTH) {
                    num = 2
                    gap = 24
                    contentLeft = '0px'
                    display = 'none'
                }
                //视口大小改变需初始化一下定位数组
                initPosition(num);
                (main as HTMLDivElement).style.setProperty('--side-width', width);
                (main as HTMLDivElement).style.setProperty('--side-display', display);
                (main as HTMLDivElement).style.setProperty('--content-left', contentLeft);
                (main as HTMLDivElement).style.setProperty('--gap', gap + 'px');
                useGlobal.setSideWidth(width)
                useGlobal.setTemplateNum(num)
                useGlobal.setGapWidth(gap)
            }
            if (entry.target.className == 'main-content') {
                const templateWidth = (inlineSize - (useGlobal.templateNum + 1)*useGlobal.gap) / useGlobal.templateNum;
                (main as HTMLDivElement).style.setProperty('--template-width', templateWidth + 'px');
                const cardWidth = useGlobal.cardWidth
                useGlobal.setCardWidth(templateWidth)
                i++
                //cardWidth发生变化才会去重新计算位置
                if(cardList.value.length > 0 && templateWidth !== cardWidth){
                    //视口大小改变需初始化一下定位数组
                    initPosition(useGlobal.templateNum);
                    setSkeFlag.value = false
                    setPosition(templateWidth,cardList.value)
                }
                //第一次进入页面请求
                if (i == 2) {
                    requestFn()
                }
            }
        })
    })
    observer.observe(main as Element);
    observer.observe(content as Element);
}

//设置数据结构
const setPosition = async (templateWidth:number, cardList:ICardItem[]) => {
    const cardCssList = cardList.map(item => {
        //根据图片的实际宽高计算出缩放后高度
        const imgHeight = item.height*templateWidth/item.width
        return {
            height: imgHeight,
            width:templateWidth,
            bgColor:item.bgColor,
            title:item.title,
            author:item.author,
            id:item.id,
            likeCount:item.likeCount,
            loading:item.loading,
        }
    })
    useGlobal.setCardList(cardCssList)
    await nextTick()
    setCardPosition()
}

let preIndex = 0 //已经定位的卡片索引
let positionArray: number[] = [] //存放定位数据的数组
const initPosition = (num:number) => {
  positionArray = new Array(num).fill(0)
  preIndex = 0
}

//nextTick挂载后重新设置卡片定位
const setCardPosition = () => {
    const imgDoms = document.querySelectorAll('.img-item') as NodeListOf<HTMLDivElement>
    imgDoms.forEach((item,index) => {
        //只需要定位还没有定位的卡片
        if(index >= preIndex ){
            //找到数组中最小的值，作为dom的y轴偏移量
            const top = Math.min.apply(null, positionArray)
            //找到当前值的数组索引，并重新赋值
            const currentIndex = positionArray.indexOf(top)
            positionArray[currentIndex] = positionArray[currentIndex] + item.getBoundingClientRect().height + 15
            item.style.transform = `translate(${currentIndex * (useGlobal.gap + useGlobal.cardWidth)}px,${top}px)`
        }
    })
    if(!setSkeFlag.value){
        preIndex = imgDoms.length
    }
    //设置容器高度
    useGlobal.setClientHeight(Math.max.apply(null, positionArray))
}

//获取数据
const getData = (pageNumber:number,pageSize:number) => {
    return new Promise<{list:ICardItem[],total:number}>(resolve => {
        setTimeout(() => {
            resolve({list: requestData.list.slice((pageNumber - 1) * pageSize, pageNumber * pageSize) ,total: requestData.total})
        },1000)
    })
}

const requestFn = async () => {
    if (requestType.finsh == true)
        return
    requestType.loading = true;
    requestType.first = false
    setSkeleton()
    const { list, total } = await getData(requestType.pageNumber, requestType.pageSize)
    requestType.loading = false
    cardList.value = cardList.value.concat(list)
    if (total == cardList.value.length) {
        requestType.finsh = true
    }
    requestType.pageNumber++
    setSkeFlag.value = false
    setPosition(useGlobal.cardWidth, cardList.value)
}

//设置骨架屏
const setSkeFlag = ref(false)
const setSkeleton = () => {
    setSkeFlag.value = true
    const loadingList = new Array(requestType.pageSize).fill({ loading: true, height: 280, width: useGlobal.cardWidth })
    setPosition(useGlobal.cardWidth, cardList.value.concat(loadingList))
}

onMounted(() => {
    mainResize()
    document.addEventListener('scroll', () => {
        //如果滚动条距离顶部的距离与可视区域的高度之和等于滚动条的高度，则滚动条触底
        if(document.documentElement.scrollTop + document.documentElement.clientHeight >= document.documentElement.scrollHeight){
            console.log(11)
            requestFn()
        }
    })
})
</script>

<style scoped lang="scss">
.app-content {
    max-width: var(--maxWidth);
    min-width: 320px;
    margin: 0 auto;
    height: 100%;

    .content {
        width: 100%;
        height: 100%;
        display: flex;
    }
}
</style>
